package com.rorochen.server.gotty;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.channels.Channel;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author chenqi
 * @date 2021-12-08 17:03
 */
public class GottyEventLoopGroup implements EventLoopGroup {

    public static final Logger log= LoggerFactory.getLogger(GottyEventLoopGroup.class);


    private AtomicInteger childIndex=new AtomicInteger(0);

    private EventLoop[] children;
    private Thread[] eventLoopThreads;

    private ExecutorService executorService;

    private LinkedList<ChainHandler> chainHandlerLinkedList=new LinkedList<>();


    private ThreadFactory threadFactory;






    public GottyEventLoopGroup(){
        threadFactory=new ThreadFactory() {
            int i=0;

            @Override
            public Thread newThread(Runnable r) {
                Thread thread=new Thread(r);
                thread.setName("group-"+i++);
                return thread;
            }
        };


        int groupLength=10;
        children=new GottyEventLoop[groupLength];
        eventLoopThreads=new Thread[groupLength];
        for (int i = 0; i <groupLength ; i++) {
            try {
                this.children[i]=new GottyEventLoop();
                this.eventLoopThreads[i]=threadFactory.newThread(this.children[i]);
            } catch (IOException e) {
                log.info("初始化eventloop错误");
            }
        }


    }


    @Override
    public EventLoop next() {
        int length=children.length;
        int index=0;
        int oldIndex=0;
        do{
            oldIndex=childIndex.get();
            index=oldIndex;
            index++;
            if( index == length){
                index=0;
            }
        }while (!childIndex.compareAndSet(oldIndex,index));
        return this.children[index];
    }

    @Override
    public void register(SelectableChannel var1) {
        try {
            this.next().register(var1);
        } catch (ClosedChannelException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void shutDown() {
        for(Thread thread : this.eventLoopThreads){
            try {
                thread.interrupt();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }



    @Override
    public void start() {
        for(Thread thread : this.eventLoopThreads){
            if(thread.getState()==Thread.State.NEW){
                thread.start();
            }else {
                log.info("创建线程异常：{}",thread);
            }
        }
    }
}
